<template>
  <div class="shareDetail" v-if="articleDetail.author">
    <!-- 导航栏 -->
    <hmnavbar path="/find" />
    <!-- 文章详情区域 -->
    <div class="content" ref="content">
      <h3>{{ articleDetail.title }}</h3>
      <div class="author">
        <div class="avatar">
          <img :src="baseURL + articleDetail.author.avatar" alt="" />
        </div>
        <div class="info">
          <div class="name">{{ articleDetail.author.nickname }}</div>
          <div class="time">{{ articleDetail.created_at | getTime }}</div>
        </div>
      </div>
      <div class="article" v-html="articleDetail.content"></div>
      <div class="comments">
        <div class="title">评论<sup>23</sup></div>
        <van-list
          v-model="loading"
          :finished="finished"
          finished-text="没有更多了"
          @load="onLoad"
        >
          <!-- 将每一条评论都传给子组件，由子组件进行渲染 -->
          <!-- 接收子组件传递的方法 -->
          <comment
            :item="item"
            v-for="(item, index) in commentsList"
            :key="index"
            @clickAva="replayCom"
          ></comment
        ></van-list>
      </div>
      <div class="addcom">
        <!-- 被点击弹出评论面板 -->
        <div class="input" @click="openPop">我来补充两句</div>
        <div class="item">
          <!-- 当前文中被当前登陆的用户收藏就就是红色的星星（根据vuex中保存的userInfo判断) +id 隐式转换将字符串转成数值-->
          <i
            :class="{
              iconicon_pingfen_sel: getStatus(id, 'collectArticles'),
              iconbtn_shoucang_sel: !getStatus(id, 'collectArticles')
            }"
            class="iconfont"
            @click="collect"
          ></i>
          {{ articleDetail.collect }}
        </div>
        <div class="item">
          <i
            @click="star"
            :class="{
              iconbtn_dianzan_big_sel: getStatus(id, 'starArticles'),
              iconbtn_dianzan_big_nor: !getStatus(id, 'starArticles')
            }"
            class="iconfont"
          ></i>
          {{ articleDetail.star }}
        </div>
        <div class="item">
          <i class="iconfont iconbtn_share" @click="share"></i>
          {{ articleDetail.share }}
        </div>
      </div>
    </div>
    <!-- 添加评论面板 -->
    <van-popup v-model="showCom" position="bottom">
      <div class="comPop">
        <!-- placeholder:有值，说明是回复评论，没值就是添加评论 -->
        <textarea v-model="value" :placeholder="placeholder"></textarea>
        <div class="send">
          <span v-if="value.trim().length === 0">发送</span>
          <!-- 输入框中有内容，发送变成红色，而且可以被点击 -->
          <span @click="sendCom" v-else :class="{ active: value.length > 0 }"
            >发送</span
          >
        </div>
      </div>
    </van-popup>
    <!-- 分享面板 -->
    <van-popup v-model="showShare">
      <div class="share">
        <div class="title">长按图片下载并分享</div>
        <div class="white" style="background-color:#fff">
          <div class="img">
            <img :src="imgURL" alt="" />
          </div>
          <div class="logo">
            <img src="../../../assets/img_share_logo@2x.png" alt="" />
          </div>
          <div class="ewm" id="qrcode" ref="qrcode"></div>
          <p>长按识别二维码查看原文</p>
        </div>
      </div>
    </van-popup>
  </div>
</template>
<script>
import comment from './comment'
// 导入封装的网络请求
import {
  getArticleApi,
  getCommentsApi,
  addCommentApi,
  collectApi,
  starApi
} from '../../../api/find.js'
// 导入vuex的辅助函数
import { mapState, mapGetters } from 'vuex'
// 导入截屏和生成二维码的插件
import html2canvas from 'html2canvas'
import QRCode from 'qrcodejs2'
export default {
  components: {
    comment
  },
  computed: {
    // 获取vuex中的userInfo
    ...mapState(['userInfo']),
    ...mapGetters(['getStatus'])
  },
  data () {
    return {
      // 保存当前文章的id
      id: this.$route.params.id,
      articleDetail: {} /* 文章详情 */,
      baseURL: process.env.VUE_APP_BASEURL,
      limit: 5,
      start: 0,
      commentsList: [] /* 渲染的评论列表 */,
      loading: false,
      finished: false,
      total: 0 /* 评论的总条数 */,
      showCom: false /* 控制评论面板的显示与隐藏 */,
      value: '' /* textarea中的内容 */,
      placeholder: '',
      comDetail: {},
      showShare: false /* 控制分享面板显示与隐藏 */,
      imgURL: '' /* 截屏图片的路径 */
    }
  },
  async created () {
    // 根据当前文章的id发送请求获取文章详情
    const res = await getArticleApi(this.id)
    // 保存文章详情并渲染到结构中
    this.articleDetail = res.data
  },

  methods: {
    // 每次评论列表加载时会执行的操作
    async onLoad () {
      // 根据当前文章的id获取文章对应的评论
      const res = await getCommentsApi({
        id: this.id,
        limit: this.limit,
        start: this.start
      })
      // 将每次加载获取的评论列表都添加到渲染的评论列表中
      this.commentsList.push(...res.data.list)
      this.total = res.data.total
      // 每次加载完就将加载状态改回来
      this.loading = false
      // 并将下一次的起始位置设置好
      this.start += this.limit
      // 当所有评论都加载了，再上拉就不会加载
      if (this.commentsList.length >= this.total) {
        this.finished = true
      }
    },
    // 点击评论输入框
    openPop () {
      // 1.打开评论面板
      this.showCom = true
      // 2.清空placeholder
      this.placeholder = ''
    },
    // 添加评论功能&回复评论功能
    async sendCom () {
      // 操作之前先验证用户是否登录
      if (!this.$login()) {
        // 未登录就终止代码执行
        return
      }

      // 登录了就正常向下执行代码

      // 根据placeholder判断当前是回复评论还是添加评论
      if (!this.placeholder) {
        // 根据文章id和评论内容发送添加评论的请求
        const res = await addCommentApi({
          content: this.value,
          article: this.id
        })
        // 由于后台不给力，需要手动添加新添加评论的被点赞的个数
        res.data.star = 0
        // 将添加的评论渲染到结构中，并且显示在最上面
        this.commentsList.unshift(res.data)
      } else {
        // 根据文章id，评论内容和被回复的评论的id发送回复评论请求
        const res = await addCommentApi({
          content: this.value,
          article: this.id,
          parent: this.comDetail.id
        })
        // 将回复的内容添加到被回复的评论的children_comments中
        this.comDetail.children_comments.push(res.data)
      }
      // 将面板关闭，并且将输入框中的内容清空
      this.showCom = false
      this.value = ''
    },
    // 点击头像回复评论的功能
    replayCom (comDetail) {
      // 1.打开评论面板
      this.showCom = true
      // 2.设置placeholder
      this.placeholder = '回复：' + comDetail.author.nickname
      // 3.存储被操作的评论的数据
      this.comDetail = comDetail
    },
    // 收藏文章&取消收藏
    async collect () {
      // 操作之前先验证用户是否登录
      if (!this.$login()) {
        // 未登录就终止代码执行
        return
      }

      // 登录了就正常向下执行代码

      // 发送请求
      const res = await collectApi({
        id: this.id
      })
      // 将该文章一共有多少点赞更新到页面
      this.articleDetail.collect = res.data.num
      // 重新获取userInfo
      this.$store.dispatch('setUserInfoAsync')
    },
    // 分享文章功能
    share () {
      // 操作之前先验证用户是否登录
      if (!this.$login) {
        // 未登录就终止代码执行
        return
      }

      // 登录了就正常向下执行代码

      // 1.显示分享面板
      this.showShare = true
      // 2.截屏
      html2canvas(this.$refs.content).then(canvas => {
        const dataURL = canvas.toDataURL('image/png')
        this.imgURL = dataURL
      })
      // 为避免dom渲染没完成就执行生成二维码的方法，将其改成异步操作
      this.$nextTick(() => {
        // 3.生成二维码
        this.qrcode()
      })
    },
    // 生成二维码的方法
    qrcode () {
      // 每次生成二维码都将之前的二维码清空
      this.$refs.qrcode.innerHTML = ''
      const qrcode = new QRCode('qrcode', {
        width: 72, // 设置宽度，单位像素
        height: 72, // 设置高度，单位像素
        text: 'https://www.baidu.com' // 设置二维码内容或跳转地址
      })
      console.log(qrcode)
    },
    // 点赞文章&取消点赞
    async star () {
      // 操作之前先验证用户是否登录
      if (!this.$login()) {
        // 未登录就终止代码执行
        return
      }

      // 登录了就正常向下执行代码

      // 根据文章id发送点赞&取消点赞请求
      const res = await starApi(this.id)
      // 更新当前文章被点赞的数量
      this.articleDetail.star = res.data.num
      // 更新用户信息（更新当前用户的点赞文章列表）
      this.$store.dispatch('setUserInfoAsync')
    }
  }
}
</script>
<style lang="less" scoped>
.shareDetail {
  .active {
    color: #e40137;
  }
  .iconicon_pingfen_sel {
    color: #e40137;
  }
  .iconbtn_dianzan_big_sel {
    color: #e40137;
  }
  background-color: #f7f4f5;
  padding-bottom: 70px;
  .content {
    h3 {
      font-size: 18px;
      line-height: 1.5em;
      padding: 20px 15px;
      background-color: #fff;
    }
    .author {
      display: flex;
      background-color: #fff;
      padding: 0 15px 20px;
      .avatar {
        margin-right: 10px;
        img {
          width: 35px;
          height: 35px;
          border-radius: 50%;
        }
      }
      .info {
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        font-size: 12px;
        .name {
          color: #545671;
          font-weight: 600;
        }
        .time {
          color: #b4b4bd;
        }
      }
    }
    .article {
      background-color: #fff;
      padding: 0 15px;
      font-size: 16px;
      line-height: 1.5em;
      padding-bottom: 20px;
      // 动态渲染的数据不能直接设置样式，要在元素前加上/deep/才有效
      /deep/ img {
        width: 100%;
      }
    }
    .comments {
      background-color: #fff;
      padding: 0 15px;
      margin-top: 10px;
      .title {
        font-size: 18px;
        color: #222222;
        font-weight: 600;
        padding-top: 20px;
        sup {
          margin-left: 4px;
          color: #b4b4bd;
          font-weight: 400;
        }
      }
    }
    .addcom {
      display: flex;
      align-items: center;
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100%;
      background-color: #fff;
      padding: 10px 15px;
      font-size: 12px;
      color: #b4b4bd;
      box-sizing: border-box;
      .input {
        flex: 1;
        background-color: #f7f4f5;
        height: 34px;
        line-height: 34px;
        border-radius: 4px;
        padding-left: 10px;
      }
      .item {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        text-align: center;
        margin-left: 25px;
        .iconfont {
          font-size: 28px;
        }
      }
    }
  }
  .comPop {
    padding: 25px 15px;
    box-sizing: border-box;
    textarea {
      width: 90%;
      height: 100px;
      background-color: #f7f4f5;
      color: #181a39;
      font-size: 14px;
      border: none;
      padding: 15px;
    }
    .send {
      font-size: 16px;
      margin-top: 10px;
      color: #b4b4bd;
      text-align: right;
    }
  }
  .share {
    padding: 13px;
    background-image: url(../../../assets/img_share_bj.png);
    background-size: cover;
    .title {
      font-size: 12px;
      color: #fff;
      text-align: center;
      padding-bottom: 10px;
    }
    .img {
      width: 286px;
      height: 300px;
      overflow: hidden;
      img {
        width: 100%;
      }
    }
    .logo {
      width: 120px;
      height: 36px;
      margin: 25px auto;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .ewm {
      width: 72px;
      height: 72px;
      margin: 0 auto;
    }
    p {
      text-align: center;
      color: #b4b4bd;
      font-size: 14px;
      padding: 14px 0 26px;
    }
  }
}
</style>
